1GB Page Table Support for HVM Guest 3/3
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 6 Apr 2010 06:09:35 +0000 (07:09 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 6 Apr 2010 06:09:35 +0000 (07:09 +0100)
This patch adds a new field in hvm to indicate 1gb is supported by
CPU.  In addition, users can turn 1GB feature on/off using a Xen
option ("hap_1gb", default is off). Per Tim's suggestion, I also add
an assertion check in shadow/common.c file to prevent affecting shadow
code.

Signed-off-by: Wei Huang <wei.huang2@amd.com>
Acked-by: Dongxiao Xu <dongxiao.xu@intel.com>
Acked-by: Tim Deegan <tim.deegan@citrix.com>
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/hvm/vmx/vmx.c
xen/arch/x86/mm/p2m.c
xen/arch/x86/mm/shadow/common.c
xen/include/asm-x86/hvm/hvm.h

index 8cc636e182b06983e73dc7f358459b3a49e32bd9..cbd5d79be59a18d03da84acfdf55aff5d679c434 100644 (file)
@@ -884,6 +884,8 @@ void start_svm(struct cpuinfo_x86 *c)
                          cpuid_edx(0x8000000A) : 0);
 
     svm_function_table.hap_supported = cpu_has_svm_npt;
+    svm_function_table.hap_1gb_pgtb = 
+        (CONFIG_PAGING_LEVELS == 4)? !!(cpuid_edx(0x80000001) & 0x04000000):0;
 
     hvm_enable(&svm_function_table);
 }
index d188749273c94ef560ff52208c0afc68996d8576..2c7df5f729bc711cc7215b13bf875ffefe33d091 100644 (file)
@@ -1445,6 +1445,8 @@ void start_vmx(void)
 
     if ( cpu_has_vmx_ept )
         vmx_function_table.hap_supported = 1;
+    
+    vmx_function_table.hap_1gb_pgtb = 0;
 
     setup_vmcs_dump();
 
index bbe7cf94c6e2b172efea1b563b7c6e9717d9d29e..7bb904d395eb9b1278603d66ee4555e51f015047 100644 (file)
 #define P2M_AUDIT     0
 #define P2M_DEBUGGING 0
 
+/* turn on/off 1GB host page table support for hap */
+static int opt_hap_1gb = 0;
+boolean_param("hap_1gb", opt_hap_1gb);
+
 /* Printouts */
 #define P2M_PRINTK(_f, _a...)                                \
     debugtrace_printk("p2m: %s(): " _f, __func__, ##_a)
@@ -1736,9 +1740,9 @@ int set_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
     while ( todo )
     {
         if ( is_hvm_domain(d) && paging_mode_hap(d) )
-            order = ( (((gfn | mfn_x(mfn) | todo) & ((1ul << 18) - 1)) == 0) ) ?
-                18 :
-            (((gfn | mfn_x(mfn) | todo) & ((1ul << 9) - 1)) == 0) ? 9 : 0;
+            order = ( (((gfn | mfn_x(mfn) | todo) & ((1ul << 18) - 1)) == 0) &&
+                      hvm_funcs.hap_1gb_pgtb && opt_hap_1gb ) ? 18 :
+                (((gfn | mfn_x(mfn) | todo) & ((1ul << 9) - 1)) == 0) ? 9 : 0;
         else
             order = 0;
 
index 36f92760cf9f9320f2f48c2363a65671d14862dd..beac5278f4a897ee22fdfef845eddc4d2d6132cf 100644 (file)
@@ -3452,6 +3452,11 @@ static void sh_unshadow_for_p2m_change(struct vcpu *v, unsigned long gfn,
 {
     struct domain *d = v->domain;
 
+    /* The following assertion is to make sure we don't step on 1GB host
+     * page support of HVM guest. */
+    ASSERT(!(level > 2 && (l1e_get_flags(*p) & _PAGE_PRESENT) &&
+             (l1e_get_flags(*p) & _PAGE_PSE)));
+
     /* If we're removing an MFN from the p2m, remove it from the shadows too */
     if ( level == 1 )
     {
index 0ae7e7ea0a868ae93e3231b7636ee3596116bb68..f52a26c2cd087b94b933f443a9d2f4658387842f 100644 (file)
@@ -69,6 +69,10 @@ struct hvm_function_table {
     /* Support Hardware-Assisted Paging? */
     int hap_supported;
 
+    /* Support 1GB Harware-Assisted Paging? */
+    int hap_1gb_pgtb;
+
+
     /*
      * Initialise/destroy HVM domain/vcpu resources
      */